package com.ch.util;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public class DBUtill {

    // 创建连接池引用
    private static DataSource dataSource;

    // 声明一个静态的线程局部变量，用于在多线程环境下存储连接对象，保证每个线程使用独立的数据库连接
    private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();

    // 在项目启东市，即创建连接池对象，赋值给dataSource
    static {
        try {
            // 创建一个 Properties 对象，用于存储属性文件中的键值对数据
            Properties properties = new Properties();
            // 通过 DBUtill 类的类加载器获取资源文件的输入流
            InputStream inputStream = DBUtill.class.getClassLoader().getResourceAsStream("jdbc.properties");
            // 加载属性文件中的内容到 Properties 对象中
            properties.load(inputStream);

            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // 对外提供在连接池中获取连接的方法
    public static Connection getConnection(){
        try {
            // 在threadLocal中获取Connection
            Connection connection = threadLocal.get();
            // threadLocal里没有存储Connection，也就是第一次获取
            if(connection == null){
                // 在连接池中获取一个连接，存储在threadLocal里
                connection = dataSource.getConnection();
            }
            return connection;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    // 对外提供回收连接的方法
    public static void release(){

        try {
            // 从线程局部变量中获取连接对象
            Connection connection = threadLocal.get();

            // 如果连接对象不为null，说明当前线程持有连接，需要将连接关闭并从线程局部变量中移除
            if(connection != null){
                // 从线程局部变量中移除连接对象，确保连接对象的释放
                threadLocal.remove();
                // 如果开启了事务的手动提交，操作完毕后，归还给连接池之前，要将事务的自动提交改为true
                connection.setAutoCommit(true);
                // 关闭数据库连接，释放资源
                connection.close();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    }




}
